package com.zjw.jwdatacenter;


import com.zjw.jwdatacenter.handler.SignalWebSocketHandler1;
import com.zjw.jwdatacenter.handler.SignalWebSocketHandler2;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;

/**
 * 专用于web前端程序连接的websocket服务端。
 *
 * @author ZJW
 * @email 1192935956@qq.com
 * @date 2025/8/9 0:09
 */
@Component
@Slf4j
public class NettyWebSocketServer2 {

    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    private Channel serverChannel;

    // WebSocket 端口，QMT客户端将连接此端口
    private static final int WEBSOCKET_PORT = 8092;

    //    @PostConstruct
    @EventListener(ApplicationReadyEvent.class)
    public void start() throws Exception {
        bossGroup = new NioEventLoopGroup(1);
        workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new HttpServerCodec());
                            pipeline.addLast(new HttpObjectAggregator(65536));
                            pipeline.addLast(new ChunkedWriteHandler());
                            // 添加 IdleStateHandler
                            // readerIdleTime: 读超时 (秒), 如果在此时间内未收到任何消息 (包括 Ping), 触发事件
                            // writerIdleTime: 写超时 (秒), 如果在此时间内未发送任何消息, 触发事件
                            // allIdleTime: 读写超时 (秒)
                            pipeline.addLast("idleStateHandler", new IdleStateHandler(30, 30, 10)); // 例如：30秒无写操作则触发
                            // WebSocket 协议处理器，处理握手、ping/pong 等
                            pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); // 路径
                            // 自定义的消息处理器
                            pipeline.addLast(new SignalWebSocketHandler2());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

//            serverChannel = b.bind(WEBSOCKET_PORT).sync().channel();
//            System.out.println("Netty WebSocket Server started on port: " + WEBSOCKET_PORT);
//            serverChannel.closeFuture().sync();

            // 在独立线程中启动 Netty
            new Thread(() -> {
                try {
                    // 绑定端口并同步等待
                    serverChannel = b.bind(WEBSOCKET_PORT).sync().channel();
//                    System.out.println("Netty WebSocket Server started on port: " + WEBSOCKET_PORT);
                    log.info("Netty WebSocket Server started on port: {}", WEBSOCKET_PORT);

                    // 阻塞等待服务器关闭（直到调用 channel.close() 或应用退出）
                    serverChannel.closeFuture().sync();
                } catch (Exception e) {
                    e.printStackTrace();
                    System.err.println("Netty server start failed on port " + WEBSOCKET_PORT);
                    log.info("Netty server start failed on port: {}", WEBSOCKET_PORT);
                } finally {
                    // 确保线程池关闭
                    if (workerGroup != null) {
                        workerGroup.shutdownGracefully();
                    }
                    if (bossGroup != null) {
                        bossGroup.shutdownGracefully();
                    }
                }
            }, "netty-websocket-server").start();
        } finally {
//            workerGroup.shutdownGracefully();
//            bossGroup.shutdownGracefully();
        }
    }

    @PreDestroy
    public void stop() {
        if (workerGroup != null) {
            workerGroup.shutdownGracefully();
        }
        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }
    }
}
